// import {
//   ArgumentMetadata,
//   BadRequestException,
//   Injectable,
//   PipeTransform,
// } from '@nestjs/common';
// import { plainToClass } from 'class-transformer';
// import { validate } from 'class-validator';

// @Injectable()
// export class ValidationPipe implements PipeTransform {
//   async transform(value: any, { metatype }: ArgumentMetadata) {
//     if (!metatype || !this.toValidate(metatype)) {
//       // 如果没有传入验证规则，则不验证，直接返回数据
//       return value;
//     }
//     // 将对象转换为 Class 来验证
//     const object = plainToClass(metatype, value);
//     const errors = await validate(object);
//     if (errors.length > 0) {
//       const msg = Object.values(errors[0].constraints)[0]; // 只需要取第一个错误信息并返回即可
//       // 自定义校验返回格式
//       throw new BadRequestException(`参数校验失败: ${msg}`);
//     }
//     return value;
//   }
//   private toValidate(metatype: any): boolean {
//     const types: any[] = [String, Boolean, Number, Array, Object];
//     return !types.includes(metatype);
//   }
// }
import {
  ArgumentMetadata,
  BadRequestException,
  Injectable,
  PipeTransform,
} from '@nestjs/common';
import { plainToClass } from 'class-transformer';
import { validate, ValidationError } from 'class-validator';

@Injectable()
export class ValidationPipe implements PipeTransform {
  async transform<T extends object>(
    value: unknown,
    { metatype }: ArgumentMetadata,
  ): Promise<T> {
    if (!metatype || !this.toValidate(metatype as new () => T)) {
      return value as T;
    }

    const object = plainToClass(metatype, value) as T;
    const errors = await validate(object);

    if (errors.length > 0) {
      throw new BadRequestException(
        `参数校验失败: ${this.extractFirstErrorMessage(errors)}`,
      );
    }

    return object;
  }

  private toValidate<T extends object>(metatype: new () => T): boolean {
    const types: (new () => any)[] = [String, Boolean, Number, Array, Object];
    return !types.some((type) => metatype === type);
  }

  private extractFirstErrorMessage(errors: ValidationError[]): string {
    if (!errors || errors.length === 0) {
      return '验证错误';
    }

    const flattenError = (error: ValidationError): string => {
      if (error.constraints) {
        return Object.values(error.constraints)[0] || '验证失败';
      }

      if (error.children?.length) {
        return flattenError(error.children[0]);
      }

      return '未知验证错误';
    };

    return flattenError(errors[0]);
  }
}
